package com.mantou.scucorse.core.service;

import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.domain.Sort.Order;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.mantou.scucorse.core.entity.ScuCourse;
import com.mantou.scucorse.core.entity.Task;
import com.mantou.scucorse.core.entity.User;
import com.mantou.scucorse.core.repository.CookieRepository;
import com.mantou.scucorse.core.repository.ScuCourseRepository;
import com.mantou.scucorse.core.repository.TaskRepository;
import com.mantou.scucorse.core.repository.UserRepository;
import com.mantou.scucorse.core.service.TaskService;
import com.mantou.scucorse.utils.CourseStatus;
import com.mantou.scucorse.utils.SystemInfo;
import com.mantou.scucorse.utils.TaskStatus;
import com.mantou.scucorse.utils.UserSatus;

@Service
public class TaskService {


	@Resource
	private TaskRepository taskRepo;

	@Resource
	private UserRepository userRepo;

	@Resource
	private ScuCourseRepository scuCourseRepository;
	
	@Transactional
	public int create(Task task) {
		return taskRepo.insert(task);
	}

	@Transactional
	public int createSelective(Task task) {
		return taskRepo.insertSelective(task);
	}

	@Transactional
	public int deleteByPrimaryKey(Integer id) {
		return taskRepo.deleteByPrimaryKey(id);
	}

	@Transactional(readOnly = true)
	public Task findByPrimaryKey(Integer id) {
		Task task = taskRepo.selectByPrimaryKey(id);
		return task;
	}

	@Transactional(readOnly = true)
	public int selectCount(Task task) {
		return taskRepo.selectCount(task);
	}

	@Transactional
	public int updateByPrimaryKey(Task task) {
		return taskRepo.updateByPrimaryKey(task);
	}

	@Transactional
	public int updateByPrimaryKeySelective(Task task) {
		return taskRepo.updateByPrimaryKeySelective(task);
	}

	public List<Task> findAvaible() {
		// TODO Auto-generated method stub
		//now it`s hard code,we get 100 task from DB per time
		Pageable pageable = new PageRequest(0,100,new Sort(new Order(Direction.ASC,"lastupdate")));
		Task queryTask = new Task();
		queryTask.setStatus(TaskStatus.RUNNING.getStatus());


		List<Task> retTask = taskRepo.selectPage(queryTask, pageable);
		int n = retTask.size();
		for(int i=0;i<n;i++){
			Task task = retTask.get(i);
			User user= userRepo.selectByPrimaryKey(task.getUserid());
			if(user == null || user.getStatus() != UserSatus.ONLNE.getStatus()){
				retTask.remove(i);
				n--;
			}
		}
		return retTask;
	}

	public List<Task> findByUserID(Integer userid) {
		// TODO Auto-generated method stub
		Task queryTask = new Task();
		queryTask.setUserid(userid);
		return taskRepo.selectPage(queryTask, new PageRequest(0,Integer.MAX_VALUE));
	}

	public Task create(String coursenumber, String sycnumber, int userid) {
		// TODO Auto-generated method stub
		ScuCourse queryScuCourse = new ScuCourse();
		queryScuCourse.setCoursenumber(coursenumber);
		queryScuCourse.setSycnumber(sycnumber);
		List<ScuCourse> scuCourses = scuCourseRepository.selectPage(queryScuCourse, new PageRequest(0,1));
		ScuCourse scuCourse;
		if(scuCourses.size() <= 0){
			scuCourse = new ScuCourse();
			scuCourse.setCoursenumber(coursenumber);
			scuCourse.setSycnumber(sycnumber);
			scuCourse.setLasdupdate(new Date());
			scuCourse.setLeftnumber(0);
			scuCourse.setStatus(CourseStatus.INITED.getStatus());
			scuCourseRepository.insertSelective(scuCourse);
			System.out.println("Course id"+scuCourse.getId());
		}else{
			scuCourse = scuCourses.get(0);
		}
		
		Task task = new Task();
		task.setCourseid(scuCourse.getId());
		task.setUserid(userid);
		
		List<Task> tasks = taskRepo.selectPage(task, new PageRequest(0,1));
		if(tasks.size()>0){
			return tasks.get(0);
		}
		task.setLastupdate(new Date());
		if(SystemInfo.taskHibrate){
			task.setStatus(TaskStatus.HIBRATE.getStatus());
		}else{
			task.setStatus(TaskStatus.RUNNING.getStatus());
		}
		taskRepo.insertSelective(task);
		return task;
	}

	public void hiberate() {
		// TODO Auto-generated method stub
		taskRepo.updatestatus(TaskStatus.RUNNING.getStatus(),TaskStatus.HIBRATE.getStatus());
	}

	public void wakeup(){
		taskRepo.updatestatus(TaskStatus.HIBRATE.getStatus(),TaskStatus.RUNNING.getStatus());
	}

	public void restart(List<Integer> restartIds,Integer userid){
		for(Integer i:restartIds){
			Task task = taskRepo.selectByPrimaryKey(i);
			if(task.getUserid() == userid && (task.getStatus() == TaskStatus.CANCELED.getStatus() || task.getStatus() == TaskStatus.ERROR.getStatus() )){
				task.setStatus(TaskStatus.RUNNING.getStatus());
				taskRepo.updateByPrimaryKey(task);
			}
		}
	}
	
	public void cancle(List<Integer> cancelIds, Integer userid) {
		// TODO Auto-generated method stub
		for(Integer i:cancelIds){
			Task task = taskRepo.selectByPrimaryKey(i);
			if(task.getUserid() == userid && task.getStatus() == TaskStatus.RUNNING.getStatus()){
				task.setStatus(TaskStatus.CANCELED.getStatus());
				taskRepo.updateByPrimaryKey(task);
			}
		}
	}
}
